package org.net5ijy.security.service.impl;

import java.util.List;

import org.net5ijy.security.bean.User;
import org.net5ijy.security.dao.UserDao;
import org.net5ijy.security.service.UserService;
import org.net5ijy.security.util.PageResult;
import org.net5ijy.security.util.PasswordEncodeUtil;
import org.net5ijy.security.util.exception.UserNotFoundException;
import org.net5ijy.security.util.exception.UsernameExistException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * UserServiceImpl
 *
 * @author XGF
 * @date 2020/11/30 22:46
 */
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class UserServiceImpl implements UserService {

  @Autowired
  private UserDao userDao;

  @Override
  public boolean saveUser(User user) {
    // 判断用户名重复
    User u = this.userDao.getUser(user.getUsername());
    if (u != null) {
      throw new UsernameExistException(user.getUsername());
    }
    // 判断手机号重复
    u = this.userDao.getUserByMobile(user.getMobile());
    if (u != null) {
      throw new UsernameExistException(user.getMobile());
    }

    String p = PasswordEncodeUtil.passwordEncode(user.getPassword());
    user.setPassword(p);
    this.userDao.saveUser(user);
    return true;
  }

  @Override
  public boolean deleteUser(Integer id) {
    User u = this.userDao.getUser(id);
    if (u == null) {
      throw new UserNotFoundException(id);
    }
    this.userDao.deleteUser(id);
    return true;
  }

  @Override
  public boolean updateUser(User user) {

    // 判断用户不存在
    User u = this.userDao.getUser(user.getId());
    // 如果用户不存在
    if (u == null) {
      throw new UserNotFoundException(user.getId());
    }
    // 判断用户名重复
    u = this.userDao.getUser(user.getUsername());
    if (u != null && !u.getId().equals(user.getId())) {
      throw new UsernameExistException(user.getUsername());
    }
    // 判断手机号重复
    u = this.userDao.getUserByMobile(user.getMobile());
    if (u != null && !u.getId().equals(user.getId())) {
      throw new UsernameExistException(user.getMobile());
    }
    // 判断用户修改了密码
    assert u != null;
    if (!u.getPassword().equals(user.getPassword())) {
      String p = PasswordEncodeUtil.passwordEncode(user.getPassword());
      user.setPassword(p);
    }
    this.userDao.updateUser(user);
    return true;
  }

  @Override
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public User getUser(Integer id) {
    User u = this.userDao.getUser(id);
    if (u == null) {
      throw new UserNotFoundException(id);
    }
    return u;
  }

  @Override
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public User getUser(String username) {
    User u = this.userDao.getUser(username);
    if (u == null) {
      throw new UsernameNotFoundException("用户名不存在: " + username);
    }
    return u;
  }

  @Override
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public User getUserByMobile(String mobile) {
    User u = this.userDao.getUserByMobile(mobile);
    if (u == null) {
      throw new UsernameNotFoundException("用户不存在: " + mobile);
    }
    return u;
  }

  @Override
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public List<User> getUsers() {
    return this.userDao.getUsers();
  }

  @Override
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public List<User> getUsers(int page, int size) {
    if (page < 0 || size < 0) {
      throw new RuntimeException("分页条件不合理: " + page + ", " + size);
    }
    return this.userDao.getUsers(page, size);
  }

  @Override
  public PageResult<User> getPageUsers(int page, int size) {
    if (page < 0 || size < 0) {
      throw new RuntimeException("分页条件不合理: " + page + ", " + size);
    }
    int count = userDao.count();
    List<User> user = userDao.getUsers(page, size);
    return new PageResult<>(user, page, size, count, 10);
  }
}
